/*
 * The MIT License (MIT)
 * Copyright © 2022 Walkline Wang (https://walkline.wang)
 * Gitee: https://gitee.com/walkline/ramcu-mechanical-keypad
 */
#include "app_common.h"
#include "uart_common.h"

/**
 * 私有变量
 */
static volatile bool uart_console_sent_flag = false;
static volatile bool uart_usb_hid_sent_flag = false;

/**
 * 全局变量
 */
volatile bool g_uart_usb_hid_recv_flag = false;
volatile uint8_t g_usb_hid_buffer[70] = {0};
volatile uint8_t g_usb_hid_buffer_counter = 0;


#ifdef __GNUC__
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
	fsp_err_t err = R_SCI_UART_Write(&g_uart_console_ctrl, (uint8_t *)&ch, 1);
    if(FSP_SUCCESS != err) __BKPT();
	while(uart_console_sent_flag == false){}
	uart_console_sent_flag = false;

	return ch;
}

int _write(int fd,char *pBuffer,int size) {
    for(int i=0;i<size;i++) {
        __io_putchar(*pBuffer++);
    }

    return size;
}

void uart_console_init(void)
{
	fsp_err_t err = R_SCI_UART_Open(&g_uart_console_ctrl, &g_uart_console_cfg);
	assert(FSP_SUCCESS == err);
	printf("uart_console initialized\r\n");
}

void uart_usb_hid_init(void)
{
	fsp_err_t err = R_SCI_UART_Open(&g_uart_usb_hid_ctrl, &g_uart_usb_hid_cfg);
	assert(FSP_SUCCESS == err);
	printf("uart_usb_hid initialized\r\n");
}

void uart_console_deinit(void)
{
	fsp_err_t err =  R_SCI_UART_Close (&g_uart_console_ctrl);

    if (FSP_SUCCESS != err) {
        printf("failed to close uart_console\r\n");
    }
}

void uart_usb_hid_deinit(void)
{
	fsp_err_t err =  R_SCI_UART_Close (&g_uart_usb_hid_ctrl);

    if (FSP_SUCCESS != err) {
        printf("failed to close uart_usb_hid\r\n");
    }
}

void uart_console_callback(uart_callback_args_t * p_args)
{
    if (p_args->event == UART_EVENT_TX_COMPLETE) {
    	uart_console_sent_flag = true;
    }
}

void uart_usb_hid_callback(uart_callback_args_t * p_args)
{
	static bool start_recv = false;
	static int16_t data_length = -255;

	switch (p_args->event) {
		case UART_EVENT_TX_COMPLETE:
			uart_usb_hid_sent_flag = true;

			break;
		case UART_EVENT_RX_CHAR:
			if ((uint8_t) p_args->data == 0x57) {
				start_recv = true;
				g_usb_hid_buffer_counter = 0;
			}

			if (start_recv) {
				if (g_usb_hid_buffer_counter == 4) {
					data_length = (int8_t) p_args->data;
				}

				g_usb_hid_buffer[g_usb_hid_buffer_counter++] = (uint8_t) p_args->data;

				if (data_length >= 0) {
					data_length--;
				} else if (data_length == -1) {
					start_recv = false;
					data_length = -255;
					g_uart_usb_hid_recv_flag = true;
				}
			}

			break;
		default:
			;
	}
}

void uart_usb_hid_send(const uint8_t *data, uint8_t len)
{
	fsp_err_t err = R_SCI_UART_Write(&g_uart_usb_hid_ctrl, &data[0], len);

	if (FSP_SUCCESS != err) {
		printf("uart_usb_hid send failed\r\n");
		return;
	}

	while (uart_usb_hid_sent_flag == false) {}
	uart_usb_hid_sent_flag = false;
}

fsp_err_t uart_usb_hid_read(uint8_t *data, uint8_t len)
{
	fsp_err_t err = R_SCI_UART_Read(&g_uart_usb_hid_ctrl, data, len);

	if (FSP_SUCCESS != err) {
		printf("uart_usb_hid read failed\r\n");
		return FSP_ERR_ABORTED;
	}

	return FSP_SUCCESS;
}
